`include "defines.v"

module ctrl (

    input  wire                 stall_pc_flag_i,

    input  wire                 flush_if_id_flag_i,
    
    input  wire                 stall_flag_from_id_i,
    
    input  wire                 flush_flag_from_exe_i,

    input  wire                 stall_3_2_1_flag_i,

    input  wire                 csr_transfer_flag_i,

    output wire[4:0]            stall_o,
    output wire[3:0]            flush_o
);

    /*******************
    index:  4       3       2       1       0
            pc      if/id   id/exe  exe/mem mem/wb
    *****************************************************
                                        stall       flush
    flush_flag_from_exe_i                           1100

    stall_flag_from_id_i                01000       0100
    
    stall_pc_flag_i                     10000
    
    flush_if_id_flag_i                              1000
    
    stall_3_2_1_flag_i                  11110       0001                当mem是访存指令时，在arbiter_to_axi中，在完成上一个取指transaction后，会暂停继续取指，如果不暂停pc的话，pc会不断自增且地址未发送出去。

    csr_transfer_flag_i                             1111
    *******************/

    // //flush_flag_from_exe_i 与 stall_flag_from_id_i 同一时间只能发生一个，所以顺序无所谓

    assign stall_o = {5{stall_flag_from_id_i}}  & 5'b01000
                   | {5{stall_pc_flag_i}}       & 5'b10000
                   | {5{stall_3_2_1_flag_i}}    & 5'b11110;

    assign flush_o = {4{csr_transfer_flag_i}}   & 4'b1111
                   | {4{flush_flag_from_exe_i}} & 4'b1100
                   | {4{stall_flag_from_id_i}}  & 4'b0100
                   | {4{flush_if_id_flag_i}}    & 4'b1000
                   | {4{stall_3_2_1_flag_i}}    & 4'b0001;
endmodule

